<template>
  <div class="graph-metric-tree">
    <a-tabs default-active-key="1" justify>
      <a-tab-pane key="1" title="可选指标">
        <div class="tab-content">
          <a-select
            v-model="defaultClassfiyId"
            placeholder="请选择"
            :options="optionMetricClassfiy"
            :field-names="{ value: 'id', label: 'name' }"
            @change="optionChange"
          >
            <template #arrow-icon>
              <IconCaretDown size="12" />
            </template>
          </a-select>
          <a-input-search
            v-model="keyword"
            @press-enter="searchData"
            @search="searchData"
            @clear="searchData"
            placeholder="请输入"
            class="mt-12"
            allow-clear
            :style="{
              borderTop: 'none',
              borderLeft: 'none',
              borderRight: 'none',
              borderRadius: '0'
            }"
          />
          <a-spin :loading="loading" class="tab-content-tree-wrapper mt-12">
            <a-tree
              class="tab-content-tree"
              blockNode
              size="small"
              :data="optionMetricData"
              :fieldNames="{
                key: 'id',
                title: 'name'
              }"
              v-model:expanded-keys="defaultExpandedKeys"
              @select="nodeSelect"
              :selected-keys="[]"
            >
              <template #title="nodeData">
                <ACloneCardBase
                  :nodeData="nodeData"
                  v-if="
                    props.drag &&
                    (!nodeData.children || !nodeData.children.length)
                  "
                >
                  <a-tooltip
                    :popup-visible="nodeData._nodeToolTipVisible"
                    :content="nodeData.name"
                  >
                    <div
                      class="custom-node"
                      @mouseenter="mouseEnter($event, nodeData)"
                      @mouseleave="mouseLeave($event, nodeData)"
                    >
                      <span
                        v-if="
                          ((nodeData._index = getMatchIndex(nodeData.name)),
                          nodeData._index < 0)
                        "
                        >{{ nodeData.name }}</span
                      >
                      <span v-else>
                        <span>
                          {{ nodeData.name.substr(0, nodeData._index) }}</span
                        >
                        <span style="color: var(--color-primary-light-4)">{{
                          nodeData.name.substr(nodeData._index, keyword.length)
                        }}</span>
                        <span>{{
                          nodeData.name.substr(nodeData._index + keyword.length)
                        }}</span>
                      </span>
                    </div>
                  </a-tooltip>
                </ACloneCardBase>
                <a-tooltip
                  v-else
                  :popup-visible="nodeData._nodeToolTipVisible"
                  :content="nodeData.name"
                >
                  <div
                    class="custom-node"
                    @mouseenter="mouseEnter($event, nodeData)"
                    @mouseleave="mouseLeave($event, nodeData)"
                  >
                    <span
                      v-if="
                        ((nodeData._index = getMatchIndex(nodeData.name)),
                        nodeData._index < 0)
                      "
                      >{{ nodeData.name + getChildrenLenStr(nodeData) }}</span
                    >
                    <span v-else>
                      <span>
                        {{ nodeData.name.substr(0, nodeData._index) }}</span
                      >
                      <span style="color: var(--color-primary-light-4)">{{
                        nodeData.name.substr(nodeData._index, keyword.length)
                      }}</span>
                      <span>{{
                        nodeData.name.substr(nodeData._index + keyword.length) +
                        +getChildrenLenStr(nodeData)
                      }}</span>
                    </span>
                  </div>
                </a-tooltip>
              </template>
            </a-tree>
          </a-spin>
        </div>
      </a-tab-pane>
      <a-tab-pane key="2" title="收藏指标">
        <div class="tab-favorite">
          <a-list :bordered="false" :split="false" hoverable size="small">
            <a-list-item
              v-for="item in favoriteMetrics"
              :key="item.id"
              @click="favoriteClick(item)"
              :class="item._isActive ? 'active' : ''"
            >
              <ACloneCardBase
                class="list-item-clone-base"
                :nodeData="{ id: item.id, name: item.cnName }"
                v-if="props.drag"
              >
                <a-tooltip
                  :popup-visible="item._nodeToolTipVisible"
                  :content="item.cnName"
                >
                  <span>{{ item.cnName }}</span>
                </a-tooltip>
              </ACloneCardBase>
              <a-tooltip
                v-else
                :popup-visible="item._nodeToolTipVisible"
                :content="item.cnName"
              >
                <span>{{ item.cnName }}</span>
              </a-tooltip>
            </a-list-item>
          </a-list>
        </div>
      </a-tab-pane>
    </a-tabs>
  </div>
</template>

<script lang="ts" setup>
import { ref } from 'vue';
import API from '@/services';
import { ACloneCardBase } from '@dangojs/a-graph-card';
import { IconCaretDown } from '@arco-design/web-vue/es/icon';
const props = withDefaults(
  defineProps<{
    width?: string;
    height?: string;
    drag?: boolean;
  }>(),
  {
    width: '220px',
    height: '100%',
    drag: false
  }
);
const emits = defineEmits(['nodeClick']);
const optionMetricData = ref<any[]>([]);
const optionMetricClassfiy = ref<any[]>([]);
const defaultClassfiyId = ref(undefined);
const loading = ref(false);
const favoriteMetrics = ref<any[]>([]);
const defaultExpandedKeys = ref<string[] | number[]>([]);
let originData: any = [];
const keyword = ref('');
// 可选指标分类切换
const optionChange = (val: any) => {
  keyword.value = '';
  getDataByRootId(val);
};

// 获取指标收藏列表
const getFavoriteMetrics = async () => {
  const { code, data = [] } = await API.favoriteMetrics.getFavoriteMetrics();
  if (code === 200) {
    favoriteMetrics.value = data.map((item: any) => {
      item._isActive = false;
      item._nodeToolTipVisible = false;
      return item;
    });
  }
};
getFavoriteMetrics();

// 获取分类下的指标树数据
const getDataByRootId = (id: number | undefined) => {
  if (id === undefined) return;
  loading.value = true;
  API.metricsGroup
    .getMetricsGroupGetGroupWithMetricsByRootId({ rootId: id })
    .then((res) => {
      loading.value = false;
      if (res.code === 200) {
        let data: any = res.data;
        addVisibleField(data.children, false);
        optionMetricData.value = originData = data.children;
        defaultExpandedKeys.value = optionMetricData.value.map(
          (item) => item.id
        );
      }
    })
    .catch(() => {
      loading.value = false;
    });
};

// 获取可选指标分类列表
const getClassfiyList = async () => {
  let { code, data = {} } = await API.metricsGroup.getMetricsGroupListRoot({
    display: 1,
    pageNum: 1,
    pageSize: 50
  });
  if (code === 200) {
    optionMetricClassfiy.value = data.list || [];
    optionMetricClassfiy.value.length &&
      (defaultClassfiyId.value = optionMetricClassfiy.value[0].id);
    getDataByRootId(defaultClassfiyId.value);
  }
};
getClassfiyList();

// 节点点击选中
const nodeSelect = (keys: any, data: any) => {
  if (data.node.children && data.node.children.length) {
    return;
  }
  emits('nodeClick', keys, data.node);
};
const favoriteClick = (item: any) => {
  emits('nodeClick', [item.id], { id: item.id, name: item.cnName });
};

const mouseEnter = (e: MouseEvent, data: any) => {
  const tar = e.target as HTMLElement;
  if (tar.scrollWidth > tar.clientWidth) {
    data._nodeToolTipVisible = true;
  }
};
const mouseLeave = (e: MouseEvent, data: any) => {
  data._nodeToolTipVisible = false;
};

// 添加tooltip控制字段
function addVisibleField(data: any[], flag = false) {
  data.forEach((item) => {
    item._nodeToolTipVisible = flag;
    if (item.children && item.children.length) {
      addVisibleField(item.children);
    }
  });
}
function searchData() {
  const loop = (data: any) => {
    const result: any = [];
    data.forEach((item: any) => {
      if (item.name.toLowerCase().indexOf(keyword.value.toLowerCase()) > -1) {
        result.push({ ...item });
      } else if (item.children) {
        const filterData = loop(item.children);
        if (filterData.length) {
          result.push({
            ...item,
            children: filterData
          });
        }
      }
    });
    return result;
  };
  optionMetricData.value = loop(originData);
}

function getMatchIndex(name: string) {
  if (!keyword.value) return -1;
  return name.toLowerCase().indexOf(keyword.value.toLowerCase());
}
function getChildrenLenStr(nodeData: any) {
  if (nodeData.children && nodeData.children.length) {
    return ' (' + nodeData.children.length + ')';
  }
  return '';
}
</script>

<style lang="scss" scoped>
.graph-metric-tree {
  height: v-bind('props.height');
  .tab-content {
    height: 100%;
    padding: 0 15px 12px;
    display: flex;
    flex-direction: column;
  }
  .tab-content-tree-wrapper {
    flex: 1;
    overflow-y: auto;
    width: 100%;
    box-sizing: border-box;
    .tab-content-tree {
      width: 100%;
    }
    .custom-node {
      width: 100%;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
  }
  .tab-favorite {
    height: 100%;
    overflow-y: auto;
  }
}
</style>

<style lang="scss">
.graph-metric-tree {
  .arco-tree-node:hover {
    background-color: var(--color-fill-2);
  }
  .arco-tree-node-title {
    overflow: hidden;
    &:hover {
      background-color: transparent;
    }
    .arco-tree-node-title-text {
      width: 100%;
    }
  }
  .arco-tree-node-title-highlight {
    background-color: transparent;
  }
  .arco-list {
    padding: 12px 0;
  }
  .arco-list-item-main {
    cursor: pointer;
    width: 100%;
    white-space: nowrap;
    .arco-list-item-content {
      overflow: hidden;
      text-overflow: ellipsis;
    }
    .clone-card-base {
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }
  }
  .arco-list-item.active .arco-list-item-content {
    color: rgb(var(--primary-6));
  }
}
</style>
